package com.apes.fn.fico.expense.platformFee.process;

import com.apes.fn.fico.expense.platformFee.CommonFeeProcess;
import com.apes.fn.scm.advancePayment.AdvancePayment;
import com.apes.fn.scm.advancePayment.AdvancePaymentItem;
import com.apes.fn.scm.advancePayment.AdvancePaymentMethod;
import com.apes.fn.scm.advancePayment.AdvancePaymentRepository;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.LogicalUtil;
import com.apes.framework.util.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 订金单生成平台费用细项单据
 * 同一单据可能满足多种条件，无法走公共方法 CommonFeeProcess 中的 createExpense 生成
 */
@Service
public class AdvancePaymentFeeProcess extends CommonFeeProcess {

    @Autowired
    private AdvancePaymentRepository advancePaymentRepository;

    @Override
    public void process(SimpleRequest request) {
        String id = request.get("id");
        AdvancePayment advancePayment = advancePaymentRepository.findOne(id);
        createExpense(advancePayment);
    }

    /**
     * 平台服务费
     *
     * @param advancePayment
     */
    private void createExpense(AdvancePayment advancePayment) {
        if ("approve".equals(advancePayment.getState())) {
            //其他
            createExpenseQT(advancePayment);
            //货币资金
            createExpenseHBZJ(advancePayment);
            //应收账款(外)
            createExpenseYSZKW(advancePayment);
        }
    }

    /**
     * 其他平台服务费
     *
     * @param advancePayment
     */
    private void createExpenseQT(AdvancePayment advancePayment) {
        List<AdvancePaymentMethod> advancePaymentMethodList = advancePayment.getPaymentMethodSet().stream()
                .filter(advancePaymentMethod -> "09".equals(advancePaymentMethod.getPaymentMethodType().getId()) &&
                        ("C0005998".equals(advancePaymentMethod.getCustomer().getId()) ||
                                "Company".equals(advancePaymentMethod.getCustomer().getRole().getId())) &&
                        advancePayment.getCompany().getParty().getId() != advancePaymentMethod.getCustomer().getParty().getId())
                .collect(Collectors.toList());
        if (advancePaymentMethodList.isEmpty()) return;
        double platformManagementFee = advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getPlatformManagementFee).sum();
        Map map = MapUtil.mapper("order", advancePayment.getId(), "orderType", "AdvancePayment",
                "source", advancePayment.getId(), "sourceBusinessType", "AdvancePayment",
                "summary", "其他", "incomeTypeId", "A09", "expenseDetailsTypeId", "002052","date",advancePayment.getCreateDate(),
                "paymentAmount", advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getAmount).sum(), "expenseAmount", platformManagementFee,
                "deptId", advancePayment.getDept().getId(), "companyId", advancePayment.getCompany().getId());
        createExpenseByFee(map);
    }

    /**
     * 货币资金服务费
     *
     * @param advancePayment
     */
    private void createExpenseHBZJ(AdvancePayment advancePayment) {
        List<AdvancePaymentMethod> advancePaymentMethodList = advancePayment.getPaymentMethodSet().stream()
                .filter(advancePaymentMethod -> LogicalUtil.notIn(advancePaymentMethod.getPaymentMethodType().getId(), "04", "10", "12", "05", "09", "003"))
                .collect(Collectors.toList());
        if (advancePaymentMethodList.isEmpty()) return;
        double platformManagementFee = advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getPlatformManagementFee).sum();
        Map map = MapUtil.mapper("order", advancePayment.getId(), "orderType", "AdvancePayment",
                "source", advancePayment.getId(), "sourceBusinessType", "AdvancePayment",
                "summary", "", "incomeTypeId", "A09", "expenseDetailsTypeId", "002051","date",advancePayment.getCreateDate(),
                "paymentAmount", advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getAmount).sum(), "expenseAmount", platformManagementFee,
                "deptId", advancePayment.getDept().getId(), "companyId", advancePayment.getCompany().getId());
        createExpenseByFee(map);
    }

    /**
     * 应收账款(外)
     *
     * @param advancePayment
     */
    private void createExpenseYSZKW(AdvancePayment advancePayment) {
        List<AdvancePaymentMethod> advancePaymentMethodList = advancePayment.getPaymentMethodSet().stream()
                .filter(advancePaymentMethod -> "09".equals(advancePaymentMethod.getPaymentMethodType().getId()) &&
                        !"C0005998".equals(advancePaymentMethod.getCustomer().getId()) &&
                        (advancePayment.getCompany().getParty().getId() != advancePaymentMethod.getCustomer().getParty().getId() ||
                                !"Company".equals(advancePaymentMethod.getCustomer().getRole().getId())))
                .collect(Collectors.toList());
        if (advancePaymentMethodList.isEmpty()) return;
        double platformManagementFee = advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getPlatformManagementFee).sum();
        Map map = MapUtil.mapper("order", advancePayment.getId(), "orderType", "AdvancePayment",
                "source", advancePayment.getId(), "sourceBusinessType", "AdvancePayment",
                "summary", "", "incomeTypeId", "A09", "expenseDetailsTypeId", "002048","date",advancePayment.getCreateDate(),
                "paymentAmount", advancePaymentMethodList.stream().mapToDouble(AdvancePaymentMethod::getAmount).sum(), "expenseAmount", platformManagementFee,
                "deptId", advancePayment.getDept().getId(), "companyId", advancePayment.getCompany().getId());
        createExpenseByFee(map);
    }

    @Override
    public Map<String, Object> getExpenseModel(Map map) {
        return null;
    }

    @Override
    public boolean support(String type) {
        return "AdvancePayment".equals(type);
    }
}
